home *** CD-ROM | disk | FTP | other *** search
/ PD Collection CD 1 / PD Collection CD 1.iso / textual / tex / files / !tex / TeXsource / commontex / c / eval < prev    next >
Encoding:
Text File  |  1988-04-18  |  18.3 KB  |  722 lines

  1. /*
  2.  *    Copyright 1986, 1987 Pat Joseph Monardo. All rights reserved.
  3.  *    Copying of this file is granted according to the provisions 
  4.  *    specified in the file COPYING which must accompany this file.
  5.  */
  6.  
  7.  
  8. /*
  9.  *              eval.c
  10.  */
  11.  
  12. #include "tex.h"
  13. #include "cmds.h"
  14. #include "heap.h"
  15. #include "arith.h"
  16. #include "char.h"
  17. #include "tfm.h"
  18. #include "eq.h"
  19. #include "eqstack.h"
  20. #include "hash.h"
  21. #include "token.h"
  22. #include "scan.h"
  23. #include "tokenstack.h"
  24. #include "evalstack.h"
  25. #include "box.h"
  26. #include "boxlists.h"
  27. #include "math.h"
  28. #include "mathlists.h"
  29. #include "cond.h"
  30. #include "def.h"
  31. #include "dvi.h"
  32. #include "pack.h"
  33. #include "page.h"
  34. #include "par.h"
  35. #include "print.h"
  36. #include "error.h"
  37. #include "eval.h"
  38.  
  39. #define vmode(CMD) \
  40.         case VMODE + CMD
  41.  
  42. #define hmode(CMD) \
  43.         case HMODE + CMD
  44.  
  45. #define non_math(M) \
  46.         case VMODE + M: \
  47.         case HMODE + M
  48.  
  49. #define mmode(CMD) \
  50.         case MMODE + CMD
  51.  
  52. #define any_mode(CMD) \
  53.         case VMODE + CMD: \
  54.         case HMODE + CMD: \
  55.         case MMODE + CMD
  56.  
  57. main_control ()
  58. {
  59.         byte    c;
  60.         fnt             f;
  61.         fourq   i;
  62.         fourq   j;
  63.         int             k;
  64.         qword   l;
  65.         ptr             p;
  66.         ptr             q;
  67.         hword   r;
  68.         int             s;
  69.         int             t;
  70.         bool    ligature_present;
  71.  
  72.  
  73.         if (every_job != NULL)
  74.                 begin_token_list(every_job, EVERY_JOB_TEXT);
  75.  
  76. big_switch:
  77.         get_x_token();
  78.  
  79. reswitch:
  80.         if (interrupt) {
  81.                 if (OK_to_interrupt) {
  82.                         back_input();
  83.                         pause_for_instructions();
  84.                         goto big_switch;
  85.                 }
  86.         }
  87.  
  88.         if (tracing_commands > 0)
  89.                 show_cur_cmd_chr();
  90.  
  91.         switch (abs(mode) + cur_cmd)
  92.         {
  93.         hmode(LETTER):
  94.         hmode(OTHER_CHAR):
  95.         hmode(CHAR_GIVEN):
  96.                 goto main_loop;
  97.         
  98.         hmode(CHAR_NUM):
  99.                 scan_char_num();
  100.                 cur_chr = cur_val;
  101.                 goto main_loop;
  102.  
  103.         hmode(SPACER):
  104.                 if (space_factor == 1000)
  105.                         goto append_normal_space;
  106.                 else app_space();
  107.                 break;
  108.         
  109.         hmode(EX_SPACE):
  110.         mmode(EX_SPACE):
  111.                 goto append_normal_space;
  112.         
  113.         any_mode(RELAX):
  114.         vmode(SPACER):
  115.         mmode(SPACER):
  116.                 break;
  117.         
  118.         any_mode(IGNORE_SPACES):
  119.                 get_nbx_token();
  120.                 goto reswitch;
  121.  
  122.         vmode(STOP):
  123.                 if (its_all_over())
  124.                         return;
  125.                 break;
  126.  
  127.         any_mode(LAST_ITEM):
  128.         any_mode(MAC_PARAM):
  129.         non_math(EQ_NO):
  130.         vmode(VMOVE):
  131.         hmode(HMOVE):
  132.         mmode(HMOVE):
  133.         vmode(VADJUST):
  134.         vmode(ITAL_CORR):
  135.                 report_illegal_case();
  136.                 break;
  137.  
  138.         non_math(SUP_MARK):
  139.         non_math(SUB_MARK):
  140.         non_math(MATH_CHAR_NUM):
  141.         non_math(MATH_GIVEN):
  142.         non_math(MATH_COMP):
  143.         non_math(DELIM_NUM):
  144.         non_math(LEFT_RIGHT):
  145.         non_math(ABOVE):
  146.         non_math(RADICAL):
  147.         non_math(MATH_STYLE):
  148.         non_math(MATH_CHOICE):
  149.         non_math(VCENTER):
  150.         non_math(NON_SCRIPT):
  151.         non_math(MKERN):
  152.         non_math(LIMIT_SWITCH):
  153.         non_math(MSKIP):
  154.         non_math(MATH_ACCENT):
  155.         mmode(ENDV):
  156.         mmode(PAR_END):
  157.         mmode(STOP):
  158.         mmode(VSKIP):
  159.         mmode(UN_VBOX):
  160.         mmode(VALIGN):
  161.         mmode(HRULE):
  162.                 insert_dollar_sign();
  163.                 break;
  164.         
  165.         vmode(HRULE):
  166.         hmode(VRULE):
  167.         mmode(VRULE):
  168.                 tail_append(scan_rule_spec());
  169.                 if (abs(mode) == VMODE)
  170.                         prev_depth = IGNORE_DEPTH;
  171.                 else if (abs(mode) == HMODE)
  172.                         space_factor = 1000;
  173.                 break;
  174.         
  175.         vmode(VSKIP):
  176.         hmode(HSKIP):
  177.         mmode(HSKIP):
  178.         mmode(MSKIP):
  179.                 append_glue();
  180.                 break;
  181.         
  182.         any_mode(KERN):
  183.         mmode(MKERN):
  184.                 append_kern();
  185.                 break;
  186.         
  187.         non_math(LEFT_BRACE):
  188.                 new_save_level(SIMPLE_GROUP);
  189.                 break;
  190.  
  191.         any_mode(BEGIN_GROUP):
  192.                 new_save_level(SEMI_SIMPLE_GROUP);
  193.                 break;
  194.  
  195.         any_mode(END_GROUP):
  196.                 if (cur_group == SEMI_SIMPLE_GROUP)
  197.                         unsave();
  198.                 else off_save();
  199.                 break;
  200.         
  201.         any_mode(RIGHT_BRACE):
  202.                 handle_right_brace();
  203.                 break;
  204.  
  205.         vmode(HMOVE):
  206.         hmode(VMOVE):
  207.         mmode(VMOVE):
  208.                 t = cur_chr;
  209.                 scan_normal_dimen();
  210.                 if (t == 0)
  211.                         saved(0) = cur_val;
  212.                 else saved(0) = -cur_val;
  213.                 scan_box();
  214.                 break;
  215.         
  216.         any_mode(LEADER_SHIP):
  217.                 saved(0) = LEADER_FLAG - A_LEADERS + cur_chr;
  218.                 scan_box();
  219.                 break;
  220.         
  221.         any_mode(MAKE_BOX):
  222.                 saved(0) = 0;
  223.                 begin_box();
  224.                 break;
  225.  
  226.         vmode(START_PAR):
  227.                 new_graf(cur_chr > 0);
  228.                 break;
  229.         
  230.         vmode(LETTER):
  231.         vmode(OTHER_CHAR):
  232.         vmode(CHAR_NUM):
  233.         vmode(CHAR_GIVEN):
  234.         vmode(MATH_SHIFT):
  235.         vmode(UN_HBOX):
  236.         vmode(VRULE):
  237.         vmode(ACCENT):
  238.         vmode(DISCRETIONARY):
  239.         vmode(HSKIP):
  240.         vmode(VALIGN):
  241.         vmode(EX_SPACE):
  242.                 back_input();
  243.                 new_graf(TRUE);
  244.                 break;
  245.         
  246.         hmode(START_PAR):
  247.         mmode(START_PAR):
  248.                 indent_in_hmode();
  249.                 break;
  250.         
  251.         vmode(PAR_END):
  252.                 normal_paragraph();
  253.                 if (mode > 0)
  254.                         build_page();
  255.                 break;
  256.  
  257.         hmode(PAR_END):
  258.                 if (align_state < 0)
  259.                         off_save();
  260.                 end_graf();
  261.                 if (mode == VMODE)      
  262.                         build_page();
  263.                 break;
  264.         
  265.         hmode(STOP):
  266.         hmode(VSKIP):
  267.         hmode(HRULE):
  268.         hmode(UN_VBOX):
  269.         hmode(HALIGN):
  270.                 head_for_vmode();
  271.                 break;
  272.         
  273.         any_mode(INSERT):
  274.         hmode(VADJUST):
  275.         mmode(VADJUST):
  276.                 begin_insert_or_adjust();
  277.                 break;
  278.         
  279.         any_mode(MARK):
  280.                 make_mark();
  281.                 break;
  282.         
  283.         any_mode(BREAK_PENALTY):
  284.                 append_penalty();
  285.                 break;
  286.         
  287.         any_mode(REMOVE_ITEM):
  288.                 delete_last();
  289.                 break;
  290.         
  291.         vmode(UN_VBOX):
  292.         hmode(UN_HBOX):
  293.         mmode(UN_HBOX):
  294.                 unpackage();
  295.                 break;
  296.         
  297.         hmode(ITAL_CORR):
  298.                 append_italic_correction();
  299.                 break;
  300.         
  301.         mmode(ITAL_CORR):
  302.                 tail_append(new_kern(0L));
  303.                 break;
  304.  
  305.         hmode(DISCRETIONARY):
  306.         mmode(DISCRETIONARY):
  307.                 append_discretionary();
  308.                 break;
  309.         
  310.         hmode(ACCENT):
  311.                 make_accent();
  312.                 break;
  313.         
  314.         any_mode(CAR_RET):
  315.         any_mode(TAB_MARK):
  316.                 align_error();
  317.                 break;
  318.  
  319.         any_mode(NO_ALIGN):
  320.                 no_align_error();
  321.                 break;
  322.         
  323.         any_mode(OMIT):
  324.                 omit_error();
  325.                 break;
  326.  
  327.         vmode(HALIGN):
  328.         hmode(VALIGN):
  329.                 init_align();
  330.                 break;
  331.         
  332.         mmode(HALIGN):
  333.                 if (privileged())
  334.                         init_align();
  335.                 break;
  336.  
  337.         vmode(ENDV):
  338.         hmode(ENDV):
  339.                 do_endv();
  340.                 break;
  341.         
  342.         any_mode(END_CS_NAME):
  343.                 cs_error();
  344.                 break;
  345.  
  346.         hmode(MATH_SHIFT):
  347.                 init_math();
  348.                 break;
  349.         
  350.         mmode(EQ_NO):
  351.                 if (privileged())
  352.                         start_eq_no();
  353.                 break;
  354.         
  355.         mmode(LEFT_BRACE):
  356.                 tail_append(new_noad()); 
  357.                 back_input();
  358.                 scan_math(nucleus(tail));
  359.                 break;
  360.  
  361.         mmode(LETTER):
  362.         mmode(OTHER_CHAR):
  363.         mmode(CHAR_GIVEN):
  364.                 if (cur_chr < 128)
  365.                         set_math_char((val)ho(math_code(cur_chr)));
  366.                 else set_math_char((val)cur_chr);
  367.                 break;
  368.         
  369.         mmode(CHAR_NUM):
  370.                 scan_char_num();
  371.                 cur_chr = cur_val;
  372.                 if (cur_chr < 128)
  373.                         set_math_char((val)ho(math_code(cur_chr)));
  374.                 else set_math_char((val)cur_chr);
  375.                 break;
  376.         
  377.         mmode(MATH_CHAR_NUM):
  378.                 scan_fifteen_bit_int();
  379.                 set_math_char(cur_val);
  380.                 break;
  381.         
  382.         mmode(MATH_GIVEN):
  383.                 set_math_char((val) cur_chr);
  384.                 break;
  385.  
  386.         mmode(DELIM_NUM):
  387.                 scan_twenty_seven_bit_int();
  388.                 set_math_char(cur_val / 010000);
  389.                 break;
  390.         
  391.         mmode(MATH_COMP):
  392.                 tail_append(new_noad());
  393.                 type(tail) = cur_chr;
  394.                 scan_math(nucleus(tail));
  395.                 break;
  396.         
  397.         mmode(LIMIT_SWITCH):
  398.                 math_limit_switch();
  399.                 break;
  400.  
  401.         mmode(RADICAL):
  402.                 math_radical();
  403.                 break;
  404.  
  405.         mmode(ACCENT):
  406.         mmode(MATH_ACCENT):
  407.                 math_ac();
  408.                 break;
  409.  
  410.         mmode(VCENTER):
  411.                 scan_spec();
  412.                 new_save_level(VCENTER_GROUP);
  413.                 normal_paragraph();
  414.                 push_nest();
  415.                 mode = -VMODE;
  416.                 prev_depth = IGNORE_DEPTH;
  417.                 if (every_vbox != NULL)
  418.                         begin_token_list(every_vbox, EVERY_VBOX_TEXT);
  419.                 break;
  420.         
  421.         mmode(MATH_STYLE):
  422.                 tail_append(new_style(cur_chr));
  423.                 break;
  424.         
  425.         mmode(NON_SCRIPT):
  426.                 tail_append(new_glue(zero_glue));
  427.                 subtype(tail) = COND_MATH_GLUE;
  428.                 break;
  429.         
  430.         mmode(MATH_CHOICE):
  431.                 append_choices();
  432.                 break;
  433.  
  434.         mmode(SUB_MARK):
  435.         mmode(SUP_MARK):
  436.                 sub_sup();
  437.                 break;
  438.         
  439.         mmode(ABOVE):
  440.                 math_fraction();
  441.                 break;
  442.         
  443.         mmode(LEFT_RIGHT):
  444.                 math_left_right();
  445.                 break;
  446.  
  447.         mmode(MATH_SHIFT):
  448.                 if (cur_group == MATH_SHIFT_GROUP)
  449.                         after_math();
  450.                 else off_save();
  451.                 break;
  452.         
  453.         any_mode(ASSIGN_TOKS):
  454.         any_mode(ASSIGN_INT):
  455.         any_mode(ASSIGN_DIMEN):
  456.         any_mode(ASSIGN_GLUE):
  457.         any_mode(ASSIGN_MU_GLUE):
  458.         any_mode(ASSIGN_FONT_DIMEN):
  459.         any_mode(ASSIGN_FONT_INT):
  460.         any_mode(SET_AUX):
  461.         any_mode(SET_PREV_GRAF):
  462.         any_mode(SET_PAGE_DIMEN):
  463.         any_mode(SET_PAGE_INT):
  464.         any_mode(SET_BOX_DIMEN):
  465.         any_mode(SET_SHAPE):
  466.         any_mode(DEF_CODE):
  467.         any_mode(DEF_FAMILY):
  468.         any_mode(SET_FONT):
  469.         any_mode(DEF_FONT):
  470.         any_mode(REGISTER):
  471.         any_mode(ADVANCE):
  472.         any_mode(MULTIPLY):
  473.         any_mode(DIVIDE):
  474.         any_mode(PREFIX):
  475.         any_mode(LET):
  476.         any_mode(SHORTHAND_DEF):
  477.         any_mode(READ_TO_CS):
  478.         any_mode(DEF):
  479.         any_mode(SET_BOX):
  480.         any_mode(TOKS_REGISTER):
  481.         any_mode(HYPH_DATA):
  482.         any_mode(SET_INTERACTION):
  483.                 prefixed_command();
  484.                 break;
  485.  
  486.         any_mode(AFTER_ASSIGNMENT):
  487.                 get_token();
  488.                 after_token = cur_tok;
  489.                 break;
  490.         
  491.         any_mode(AFTER_GROUP):
  492.                 get_token();
  493.                 save_for_after(cur_tok);
  494.                 break;
  495.  
  496.         any_mode(IN_STREAM):
  497.                 clopen_stream();
  498.                 break;
  499.  
  500.         any_mode(MESSAGE):
  501.                 issue_message();
  502.                 break;
  503.         
  504.         any_mode(CASE_SHIFT):
  505.                 shift_case();
  506.                 break;
  507.         
  508.         any_mode(XRAY):
  509.                 show_whatever();
  510.                 break;
  511.         
  512.         any_mode(EXTENSION):
  513.                 do_extension();
  514.                 break;
  515.         }
  516.         goto big_switch;
  517.  
  518. #define make_lig_disc() \
  519.         {if (ligature_present) { \
  520.                 p = new_ligature(f, l, link(q)); \
  521.                 link(q) = p; \
  522.                 tail = p;} \
  523.         if (c == hyphen_char[f] && mode == HMODE) \
  524.                 tail_append(new_disc());}
  525.  
  526. #define space_glue() \
  527.         {p = font_glue[cur_font]; \
  528.         if (p == NULL) { \
  529.                 f = cur_font; \
  530.                 p = new_spec(zero_glue); \
  531.                 k = param_base[f] + SPACE_CODE; \
  532.                 width(p) = font_info[k].sc; \
  533.                 stretch(p) = font_info[k + 1].sc; \
  534.                 shrink(p) = font_info[k + 2].sc; \
  535.                 font_glue[f] = p;}}
  536.  
  537. main_loop:
  538.         f = cur_font;
  539.         c = cur_chr;
  540.  
  541. main_loop_1:
  542.         if (c < font_bc[f] || c > font_ec[f]) {
  543.                 char_warning(f, c);
  544.                 goto big_switch;
  545.         }
  546.  
  547. main_loop_2:
  548.         q = tail;
  549.         ligature_present = FALSE;
  550.         l = qi(c);
  551.  
  552. main_loop_3:
  553.         if (c < 128) {
  554.                 s = sf_code(c);
  555.                 if (s == 1000)
  556.                         space_factor = 1000;
  557.                 else if (s < 1000) {
  558.                         if (s > 0)
  559.                                 space_factor = s;
  560.                 } else if (space_factor < 1000)
  561.                         space_factor = 1000;
  562.                 else space_factor = s;
  563.         } else space_factor = 1000;
  564.         i = char_info(f, l);
  565.         if (char_exists(i)) {
  566.                 fast_get_avail(p);
  567.                 font(p) = f;
  568.                 character(p) = qi(c);
  569.                 link(tail) = p;
  570.                 tail = p;
  571.         } else char_warning(f, qo(l));
  572.         get_next();
  573.         if (cur_cmd == LETTER ||
  574.                 cur_cmd == OTHER_CHAR ||
  575.                 cur_cmd == CHAR_GIVEN)
  576.                 r = qi(cur_chr);
  577.         else {
  578.                 x_token();
  579.                 if (cur_cmd == LETTER ||
  580.                         cur_cmd == OTHER_CHAR ||
  581.                         cur_cmd == CHAR_GIVEN)
  582.                         r = qi(cur_chr);
  583.                 else if (cur_cmd == CHAR_NUM) {
  584.                         scan_char_num();
  585.                         r = qi(cur_val);
  586.                 } else
  587.                         r = qi(256);
  588.         }
  589.         if (char_tag(i) == LIG_TAG && r != qi(256)) {
  590.                 k = lig_kern_start(f, i);
  591.                 do {
  592.                         j = font_info[k].qqqq;
  593.                         if (next_char(j) == r) {
  594.                                 if (op_bit(j) < KERN_FLAG) {
  595.                                         ligature_present = TRUE;
  596.                                         l = rem_byte(j);
  597.                                         c = qo(r);
  598.                                         goto main_loop_3;
  599.                                 } else {
  600.                                         make_lig_disc();
  601.                                         tail_append(new_kern(char_kern(f, j)));
  602.                                         c = qo(r);
  603.                                         goto main_loop_2;
  604.                                 }
  605.                         }
  606.                         incr(k);
  607.                 } while (stop_bit(j) < STOP_FLAG);
  608.         }
  609.         make_lig_disc();
  610.         if (r == qi(256))
  611.                 goto reswitch;
  612.         c = qo(r);
  613.         goto main_loop_1;
  614.  
  615. append_normal_space:
  616.         if (space_skip == zero_glue) {
  617.                 space_glue();
  618.                 q = new_glue(p);
  619.         } else
  620.                 q = new_param_glue(SPACE_SKIP_CODE);
  621.         link(tail) = q;
  622.         tail = q;
  623.         goto big_switch;
  624. }
  625.  
  626. app_space ()
  627. {
  628.         fnt             f;
  629.         int             k;
  630.         ptr             p;
  631.         ptr             q;
  632.  
  633.         if (space_factor >= 2000 && xspace_skip != zero_glue)
  634.                 q = new_param_glue(XSPACE_SKIP_CODE);
  635.         else {
  636.                 if (space_skip != zero_glue)
  637.                         p = space_skip;
  638.                 else space_glue();
  639.                 p = new_spec(p);
  640.                 if (space_factor >= 2000)
  641.                         width(p) += extra_space(cur_font);
  642.                 stretch(p) = xn_over_d(stretch(p), space_factor, 1000L);
  643.                 shrink(p) = xn_over_d(shrink(p), 1000L, space_factor);
  644.                 q = new_glue(p);
  645.                 glue_ref_count(p) = NULL;
  646.         }
  647.         link(tail) = q;
  648.         tail = q;
  649. }
  650.  
  651. insert_dollar_sign ()
  652. {
  653.         back_input();
  654.         cur_tok = MATH_SHIFT_TOKEN + '$';
  655.         print_err("Missing $ inserted");
  656.         help_dollar();
  657.         ins_error();
  658. }
  659.  
  660. report_illegal_case ()
  661. {
  662.         you_cant();
  663.         help_illegal_case();
  664.         error();
  665. }
  666.  
  667. you_cant ()
  668. {
  669.         print_err("You can't use `");
  670.         print_cmd_chr(cur_cmd, cur_chr);
  671.         print("' in ");
  672.         print_mode(mode);
  673. }
  674.  
  675. bool
  676. privileged ()
  677. {
  678.         if (mode > 0)
  679.                 return TRUE;
  680.         else {
  681.                 report_illegal_case();
  682.                 return FALSE;
  683.         }
  684. }
  685.  
  686. bool
  687. its_all_over ()
  688. {
  689.         if (privileged()) {
  690.                 if (page_head == page_tail &&
  691.                         head == tail &&
  692.                         dead_cycles == 0) {
  693.                         return TRUE;
  694.                 }
  695.                 back_input();
  696.                 tail_append(new_null_box());
  697.                 width(tail) = hsize;
  698.                 tail_append(new_glue(fill_glue));
  699.                 tail_append(new_penalty(-010000000000));
  700.                 build_page();
  701.         }
  702.         return FALSE;
  703. }
  704.  
  705. /*
  706.  * Help text
  707.  */
  708.  
  709. help_dollar ()
  710. {
  711.         help2("I've inserted a begin-math/end-math symbol since I think",
  712.         "you left one out. Proceed with fingers crossed.");
  713. }
  714.  
  715. help_illegal_case ()
  716. {
  717.         help4("Sorry, but I'm not programmed to handle this case;",
  718.         "I'll just pretend that you didn't ask for it.",
  719.         "If you're in the wrong mode, you might be able to",
  720.         "return to the right one by typing `I}' or `I$' or `I\\par'.");
  721. }
  722.